import socket, re, time, httplib, dict
# -*- coding: utf-8 -*-
#Версия 0,002
#Переписано полностью в кавайный код
#http://www.teamfair.info/DC-Protocol.htm
#http://www.teamfair.info/wiki/index.php?title=Main_Page
#Форум по DC++
#http://forum.proc.ru/index.php?showforum=24

i=1
#MAIN_CHAT = 'on'
MAIN_CHAT = 'off'
#Option

NICK='Tachikoma'
PASS=None
DESCR='print =>help'
TAG='<PyDC++BOT V:0.002>'
SHARE='0'
if i==1:
    HOST='avangard.no-ip.org'
    PORT=411
elif i==2:
    HOST='172.16.182.128'
    PORT=411
    TAG='<ApexDC++ V:(r320),M:P,H:1/0/0,S:13>'  
elif i==3:
    HOST='hub.animeforum.ru'
    PORT=4111
    TAG='<ApexDC++ V:(r320),M:P,H:1/0/0,S:13>'
    SHARE='850000000000'

#sys option
master='Apkawa'

common_help='\n\
        =>help - Вызывает эту справку.\n\
        =>call - Проверяет работоспособность бота\n\n\
        =>ej word - перевод слова с английского на японский.\n\
        =>je go - перевод слова с японского на английский\n\
        =>er word - перевод слова с английского на русский\n\
        =>re слово - перевод слова с русского на английский'
master_help='\n\n        == Команды мастера ==\n        Пишутся в приват боту.\n\
        =>m message - Отправить сообщение от имени бота. \n\
        =>pm@Nick message - Отправить в личку юзеру сообщение от имени бота.\n\
        =>kill - Завершить работу бота.    '
class dcpp:
    def __init__(self):
        self.sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.connect((HOST,PORT))
        lock=self.sock.recv(1024)
        lock_key=re.findall('\$Lock[\s](.*?)[\s]', lock)[0]
        key =self._createKey(lock).encode("utf-8")
        self.sock.send('$Key %s|$ValidateNick %s|'%(key,NICK))
        print self.view_chat()
        if PASS == None:
            self.sock.send('$Version 1,0091|$GetNickList|$MyINFO $ALL %s %s%s$ $0$$%s$|' %(NICK,DESCR,TAG,SHARE))
        else: 
            self.sock.send('$Version 1,0091|\
            $MyPass %s\
            |$GetNickList\
            |$MyINFO $ALL %s %s%s$ $0$$%s$|' %(PASS,NICK,DESCR,TAG,SHARE))
    def close(self):
        self.sock.close()
    def view_chat(self):
        return  cp1251_utf8(self.sock.recv(2048))
    def raw_view(self):
        self.sock.recv(2048)
    def send_mainchat(self, text):
        text=utf8_cp1251('<%s> %s|'%(NICK,text))
        self.sock.send(text)
    def send_pm(self,to,text):
        text=utf8_cp1251('$To: %s From: %s $<%s> %s|'%(to,NICK,NICK,text))
        self.sock.send(text)
        
    def _createKey(self,lock):# за код спасибо Окси    
                key = {}
                for i in xrange(1, len(lock)):
                        key[i] = ord(lock[i]) ^ ord(lock[i-1])
                key[0] = ord(lock[0]) ^ ord(lock[len(lock)-1]) ^ ord(lock[len(lock)-2]) ^ 5
                for i in xrange(0, len(lock)):
                        key[i] = ((key[i]<<4) & 240) | ((key[i]>>4) & 15)

                out = ''
                for i in xrange(0, len(lock)):
                        out += unichr(key[i])

                out = out.replace(u'\0', u'/%DCN000%/').replace(u'\5', u'/%DCN005%/').replace(u'\44', u'/%DCN036%/')
                out = out.replace(u'\140', u'/%DCN096%/').replace(u'\174', u'/%DCN124%/').replace(u'\176', u'/%DCN126%/')

                return out

def utf8_cp1251(text):
    u=unicode(text, 'utf8')
    cyrillic_cp1251=u.encode('cp1251')
    return cyrillic_cp1251
def cp1251_utf8(text):
    cyrillic_cp1251=unicode(text, 'cp1251')
    text=cyrillic_cp1251.encode('utf8')
    return text
def readchat(text):
    if re.search('(^\$To:)|(^<.*?>)', text) != None:
        print text

def bot_send(text,to,flag):
    if flag == 1:
        dc.send_pm(to[0], text)
    elif flag == 0:
        dc.send_mainchat(text)

def bot_answer(text, flag, to):  
    #Доступные всем команды
    en_jp=re.findall('=>ej[\s](.*?)\|',text)
    jp_en=re.findall('=>je[\s](.*?)\|',text)
    en_ru=re.findall('=>er[\s](.*?)\|',text)
    ru_en=re.findall('=>re[\s](.*?)\|',text)
    #print to
    #Master command
    user_mes = re.findall('From: %s .*?=>m[\s].*$'%master,text)
    user_mes_pm = re.findall('From:[\s]%s[\s].*?=>pm@.*?[\s].*$'%master,text)
        
    if re.search('<.*?> =>call',text) != None:
        text='Звали?'
        bot_send(text, to, flag)
    elif re.search('<.*?> =>help',text) != None: 
        if to == [master]:
            help='%s%s'%(common_help,master_help)
            bot_send(help, to, 1)
            #print to 
        else:
            bot_send(common_help, to, flag)
        
    
    elif en_jp != []:
        bot_send(dict.en_jap(en_jp[0]), to, flag)
    elif jp_en != []:
        bot_send(dict.jap_en(jp_en[0]), to, flag)
    elif en_ru != []:
        bot_send(dict.eng_rus(en_ru[0]), to, flag)
    elif ru_en != []:
        bot_send(dict.rus_eng(ru_en[0]), to, flag)
    elif user_mes != []:
        dc.send_mainchat(re.findall('=>m[\s](.*?)\|', user_mes[0])[0])
    elif user_mes_pm != []:
        print 'test'
        pm=re.findall('=>pm\@(.*?)[\s](.*?)\|', user_mes_pm[0])[0]
        dc.send_pm(pm[0],pm[1])
    elif re.search('From:[\s]%s[\s].*?=>kill'%master,text) != None:
        dc.send_pm(master, 'Так точно, хозяин')
        dc.close()
        exit()


dc=dcpp()
#time.sleep(5)
#dc.send_pm(master, 'Я тут')
#dc.send_mainchat('Всем привет! =) наберите "=>help" без кавычек')

while True:
    s=dc.view_chat()
    #s=dc.raw_view()
    #print s
    readchat(s)
    if re.search('<.*?> =>.*?\|',s) != None:
        filtered=re.sub('($MyINFO $ALL.*?)\|', '', s)
        pm = re.findall('\$To:[\s].*?From:[\s](.*?)[\s]\$',filtered)
        flag=None
        if  pm != []:
            #PM - 1
            flag=1
        else:
            #Main - 0
            if MAIN_CHAT == 'on':
                flag=0
            elif MAIN_CHAT == 'off':
                print 'Main 3'
                continue          
        bot_answer(filtered, flag, pm) 